package com.yanqu.road.server.manger.banquet;

import com.yanqu.road.dao.impl.cross.party.BanquetRelationDataDaoImpl;
import com.yanqu.road.entity.banquet.BanquetRelationshipData;
import com.yanqu.road.entity.banquet.CrossPartyRelationship;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.pb.banquet.BanquetProto;
import com.yanqu.road.server.TempMgr;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class BanquetRelationshipMgr extends TempMgr {

    private static Map<Integer, Map<Long, List<BanquetRelationshipData>>> userBanquetRelationshipMap = new ConcurrentHashMap<>();
    private static Map<Long, UserBaseInfo> userBaseInfoMap = new ConcurrentHashMap<>();

    public static void addPartyRelationship(long myUserId, long otherUserId, UserBaseInfo otherUserBaseInfo, int banquetType, long beginShowTime, boolean isMyJoin) {
        int partyType = 1;
        if (banquetType == 0 || BanquetConfigMgr.isServerNormalBanquet(banquetType)) {
            partyType = 1;
        } else if (BanquetConfigMgr.isCrossUserBanquet(banquetType)) {
            partyType = 2;
        } else {
            return;
        }
        Map<Long, List<BanquetRelationshipData>> relationMap = userBanquetRelationshipMap.get(partyType);
        if (relationMap == null) {
            relationMap = new ConcurrentHashMap<>();
            userBanquetRelationshipMap.put(partyType, relationMap);
        }

        List<BanquetRelationshipData> dataMap = relationMap.get(myUserId);
        if (dataMap == null) {
            dataMap = new ArrayList<>();
            relationMap.put(myUserId, dataMap);
        }
        BanquetRelationshipData data = null;
        for (BanquetRelationshipData relationData : dataMap) {
            if (relationData.getOtherUserId() == otherUserId) {
                data = relationData;
                break;
            }
        }
        if (data == null) {
            data = new BanquetRelationshipData();
            data.setMyUserId(myUserId);
            data.setOtherUserId(otherUserId);
            data.setPartyType(partyType);
            data.setOtherUserBaseInfo(otherUserBaseInfo);
            data.setInsertOption();
            dataMap.add(data);
        }
        data.setOtherUserBaseInfo(otherUserBaseInfo);
        long lastJoinTime = data.getLastJoinTime();
        if (lastJoinTime < beginShowTime) {
            data.setMyJoinTimes(0);
            data.setOtherJoinTimes(0);
        }
        data.setLastJoinTime(System.currentTimeMillis());
        if (isMyJoin) {
            data.setMyJoinTimes(data.getMyJoinTimes() + 1);
        } else {
            data.setOtherJoinTimes(data.getOtherJoinTimes() + 1);
        }

        // 设置到缓存内
        userBaseInfoMap.put(data.getOtherUserId(), data.getOtherUserBaseInfo());
    }

    public static Map<Long, CrossPartyRelationship> getBanquetRelationship(long userId, int partyType, long beginShowTime) {
        Map<Long, CrossPartyRelationship> relationshipMap = new ConcurrentHashMap<>();
        Map<Long, List<BanquetRelationshipData>> dataMap = userBanquetRelationshipMap.get(partyType);
        if (dataMap != null) {
            List<BanquetRelationshipData> relationDataMap = dataMap.get(userId);
            if (relationDataMap != null) {
                for (BanquetRelationshipData entry : relationDataMap) {
                    CrossPartyRelationship crossPartyRelationship = new CrossPartyRelationship();
                    long otherUser = entry.getOtherUserId();

                    UserBaseInfo userBaseInfo = entry.getOtherUserBaseInfo();
                    if (userBaseInfo == null) {
                        continue;
                    }
                    crossPartyRelationship.setUserBaseInfo(userBaseInfo);
                    crossPartyRelationship.setUserId(otherUser);
                    if (entry.getLastJoinTime() < beginShowTime) {
                        continue;
                    }
                    crossPartyRelationship.setTo(entry.getMyJoinTimes());
                    crossPartyRelationship.setFrom(entry.getOtherJoinTimes());
                    relationshipMap.put(otherUser, crossPartyRelationship);
                }
            }
        }
        return relationshipMap;
    }


    public static void initUserBanquetRelationShip(List<BanquetProto.BanquetRelationshipDataMsg> dataList) {
        for (BanquetProto.BanquetRelationshipDataMsg msg : dataList) {
            long myUserId = msg.getMyUserId();
            int myTimes = msg.getMyTimes();
            int otherTimes = msg.getOtherTimes();
            long otherUserId = msg.getOtherUserId();
            UserBaseInfo userBaseInfo = PlayerBasePb.parseBaseUserInfo(msg.getPlayerBaseData());
            long lastJoinTime = msg.getLastJoinTime();
            int partyType = msg.getType();
            Map<Long, List<BanquetRelationshipData>> relationMap = userBanquetRelationshipMap.get(partyType);
            if (relationMap == null) {
                relationMap = new ConcurrentHashMap<>();
                userBanquetRelationshipMap.put(partyType, relationMap);
            }

            List<BanquetRelationshipData> dataMap = relationMap.get(myUserId);
            if (dataMap == null) {
                dataMap = new ArrayList<>();
                relationMap.put(myUserId, dataMap);
            }

            BanquetRelationshipData data = null;
            for (BanquetRelationshipData relationData : dataMap) {
                if (relationData.getOtherUserId() == otherUserId) {
                    data = relationData;
                    break;
                }
            }
            if (data != null) {
                continue;
            }
            data = new BanquetRelationshipData();
            data.setMyUserId(myUserId);
            data.setOtherUserId(otherUserId);
            data.setPartyType(partyType);
            data.setOtherUserBaseInfo(userBaseInfo);
            data.setLastJoinTime(lastJoinTime);
            data.setInsertOption();
            dataMap.add(data);
            data.setOtherUserBaseInfo(userBaseInfo);
            data.setMyJoinTimes(myTimes);
            data.setOtherJoinTimes(otherTimes);

            // 设置userBase到缓存内
            userBaseInfoMap.put(data.getOtherUserId(), data.getOtherUserBaseInfo());
        }
    }

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        List<BanquetRelationshipData> list = new BanquetRelationDataDaoImpl().getCrossPartyRelationData(System.currentTimeMillis() - 30 * 24L * 3600 * 1000);
        for (BanquetRelationshipData data : list) {

            if(data.getOtherUserBaseInfo() == null){
                userBaseInfoMap.put(data.getOtherUserId(), new UserBaseInfo());
                continue;
            }

            // 缓存userBaseInfo
            if (userBaseInfoMap.containsKey(data.getOtherUserId())) {
                if (userBaseInfoMap.get(data.getOtherUserId()).getLastLoginTime() < data.getOtherUserBaseInfo().getLastLoginTime()) {
                    // 写入登录时间最新的那个记录
                    userBaseInfoMap.put(data.getOtherUserId(), data.getOtherUserBaseInfo());
                }
            } else {
                userBaseInfoMap.put(data.getOtherUserId(), data.getOtherUserBaseInfo());
            }

            long myUserId = data.getMyUserId();
            int partyType = data.getPartyType();
            Map<Long, List<BanquetRelationshipData>> mapMap = userBanquetRelationshipMap.get(partyType);
            if (mapMap == null) {
                mapMap = new ConcurrentHashMap<>();
                userBanquetRelationshipMap.put(partyType, mapMap);
            }
            List<BanquetRelationshipData> dataList = mapMap.get(myUserId);
            if (dataList == null) {
                dataList = new ArrayList<>();
                mapMap.put(myUserId, dataList);
            }
            dataList.add(data);
        }
        // 重新设置userBaseInfo 节省内存资源
        for (BanquetRelationshipData data : list) {
            data.setOtherUserBaseInfoNotUpdate(userBaseInfoMap.get(data.getOtherUserId()));
        }
        return true;
    }

    @Override
    public boolean save() {
        for (Map<Long, List<BanquetRelationshipData>> listMap : new ArrayList<>(userBanquetRelationshipMap.values())) {
            for (List<BanquetRelationshipData> list : new ArrayList<>(listMap.values())) {
                for (BanquetRelationshipData data : new ArrayList<>(list)) {
                    if (data.isInsertOption()) {
                        new BanquetRelationDataDaoImpl().add(data);
                    } else if (data.isUpdateOption()) {
                        new BanquetRelationDataDaoImpl().update(data);
                    }

                    data.setOtherUserBaseInfoNotUpdate(userBaseInfoMap.get(data.getOtherUserId()));
                }
            }
        }
        return true;
    }

    @Override
    public boolean stop() {
        return true;
    }

    /**
    * 描述：获取宴会成员互宴信息
    * 作者：zrq
    * 时间：2022/8/19
    * 参数：

    * 返回值：
    **/
    public static Map<Long, CrossPartyRelationship> getBanquetMemberRelationship(long userId, int partyType, long beginShowTime,
                                                                                 List<Long> memberList) {
        Map<Long, CrossPartyRelationship> relationshipMap = new ConcurrentHashMap<>();
        if(null == memberList){
            return relationshipMap;
        }
        if(memberList.size() <= 0){
            return relationshipMap;
        }
        Map<Long, List<BanquetRelationshipData>> dataMap = userBanquetRelationshipMap.get(partyType);
        if (null != dataMap) {
            List<BanquetRelationshipData> relationDataMap = dataMap.get(userId);
            if (null != relationDataMap) {
                for (BanquetRelationshipData entry : relationDataMap) {
                    long otherUser = entry.getOtherUserId();
                    if(!memberList.contains(otherUser)){
                        continue;
                    }
                    UserBaseInfo userBaseInfo = entry.getOtherUserBaseInfo();
                    if (userBaseInfo == null) {
                        continue;
                    }
                    CrossPartyRelationship crossPartyRelationship = new CrossPartyRelationship();
                    crossPartyRelationship.setUserBaseInfo(userBaseInfo);
                    crossPartyRelationship.setUserId(otherUser);
                    if (entry.getLastJoinTime() < beginShowTime) {
                        continue;
                    }
                    crossPartyRelationship.setTo(entry.getMyJoinTimes());
                    crossPartyRelationship.setFrom(entry.getOtherJoinTimes());
                    relationshipMap.put(otherUser, crossPartyRelationship);
                }
            }
        }
        return relationshipMap;
    }
}
